package com.fzq.util;


import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;

import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * jws token工具类
 */
public class TokenUtil {
    //用户密钥
    private final static String SECRET = "202cb962ac59075b964b07152d234b70";
    //常量，表示保存到载荷中内容的键
    private final static String USER_KEY = "userkey";
    //token过期时间
    public final static int TIMEOUT = 30;
    //过期时间单位  默认分钟
    public final static TimeUnit TIMEUNIT = TimeUnit.MINUTES;

    /**
     * 生成token
     *
     * @param account 保存到token中的用户帐号
     * @return 生成好的token
     */
    public static String getToken(String account) {
        String token = null;
        try {
            //生成头部，固定写法
            JWSHeader jwsHeader = new JWSHeader
                    .Builder(JWSAlgorithm.HS256)  //设置头部的加密算法
                    .type(JOSEObjectType.JWT)  //常量，要对谁进行加密
                    .build();

            //生成载荷
            Map<String, Object> map = new HashMap<String, Object>();
            map.put(USER_KEY, account);
            Payload payload = new Payload(map);//要保存的用户数据，一般是用户的帐号

            //生成签名
            JWSSigner jwsSigner = new MACSigner(SECRET);  //MACSigner()中要指定一个密钥，需要256bits
            JWSObject jwsObject = new JWSObject(jwsHeader, payload); //将头部和截荷接到签名器中
            //生成签名（头+载荷+密钥）
            jwsObject.sign(jwsSigner);
            token = jwsObject.serialize();
        } catch (JOSEException e) {
            throw new RuntimeException();
        }
        //将签名序列化为字符串
        return token;
    }

    /**
     * 验证token是否合法
     *
     * @param token 要验证的token
     * @return true:合法   false:不合法
     */
    public static boolean verify(String token) {
        try {
            JWSObject jwsObject = JWSObject.parse(token);
            JWSVerifier jwsVerifier = new MACVerifier(SECRET);//密钥要和加密时的相同
            return jwsObject.verify(jwsVerifier);
        } catch (JOSEException | ParseException e) {
            throw new RuntimeException();
        }
    }

    /**
     * 获得token中的用户名
     *
     * @param token 要解析的token
     * @return 用户的帐号
     */
    public static String getUserName(String token) {
        String username = null;
        try {
            JWSObject jwsObject = JWSObject.parse(token);
            Map<String, Object> map = jwsObject.getPayload().toJSONObject();
            username = (String) map.get(USER_KEY);
        } catch (ParseException e) {
            throw new RuntimeException();
        }
        return username;
    }
}
